package org.linotte.abaque;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.List;

import org.linotte.greffons.externe.Greffon;
import org.linotte.greffons.externe.Greffon.DocumentationHTML;

@DocumentationHTML("<i>Abaque</i> est une librairie de fonctions mathématiques.<br>"
		+ "Site officiel du greffon Abaque : <a href=http://langagelinotte.free.fr/wiki/index.php?title=Abaque>Site Abaque</a><br>"
		+ "<u>Les méthodes fonctionnelles proposées par l'espèce Abaque sont:</u><br>" + "<ul>" + "<li>abaque.factorielle(A) : Calcule la factorielle du nombre A</li>"
		+ "<li>abaque.hasard(A,B) : Calcule un nombre aléatoire entre A et B (exclu)</li>" + "</ul>" + "<li>abaque.moyenne(casier de nombres) : Calcule la moyenne des nombres</li>" + "</ul>")
public class Abaque extends Greffon {

	/**
	 * retourne un nombre aléatoire entre a et b exclu
	 * @param a
	 * @param b
	 * @return 
	 * @
	 */
	@Slot
	public int hasard(int a, int b) {
		return (int) (Math.random() * (b - a) + a);
	}

	/*
	 * ARITHMÉTIQUE
	 */

	/**
	 * retourne VRAI si n est pair et FAUX sinon avec n entier positif ou nul
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public boolean pair(BigDecimal n) throws GreffonException {
		return n.remainder(new BigDecimal(2)).intValue() == 0;
	}

	/**
	 * retourne VRAI si n est impair et FAUX sinon avec n entier positif ou nul
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public boolean impair(BigDecimal n) throws GreffonException {
		return n.remainder(new BigDecimal(2)).intValue() != 0;
	}

	/**
	 * retourne le quotient de m par n avec m entier et n entier non nul
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal quotient(BigDecimal m, BigDecimal n) throws GreffonException {
		return m.divide(n);
	}

	/**
	 * retourne le reste de la division de m par n avec m entier et n entier non nul
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal reste(BigDecimal m, BigDecimal n) throws GreffonException {
		return m.remainder(n);
	}

	/**
	 * retourne le plus grand commun diviseur de m et n avec m et n entiers
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigInteger pgcd(BigInteger m, BigInteger n) throws GreffonException {
		return m.gcd(n);
	}

	/**
	 * retourne le plus petit commun multiple de m et n avec m et n entiers
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal ppcm(BigDecimal m, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne VRAI si n est premier et FAUX sinon avec n entier positif ou nul
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public boolean premier(BigInteger n) throws GreffonException {
		return n.isProbablePrime(200);
	}

	/**
	 * retourne la suite des nombres premiers inférieurs à n avec n entier positif ou nul
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> listepremiers(BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la suite des diviseurs du nombre n avec n entier positif
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> diviseurs(BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la suite des facteurs premiers de n avec n entier positif ou nul.
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> factorise(BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * transforme le nombre m écrit en base b1 sous forme de chaîne de caractères en un nombre écrit en base b2 lui aussi sous forme de chaîne de caractères
	 * @param m
	 * @param b1
	 * @param b2
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal changebase(BigDecimal m, BigDecimal b1, BigDecimal b2) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/*
	 * PROBABILITÉS ET STATISTIQUES
	 */

	/**
	 * retourne la factorielle de n avec n entier positif ou nul
	 * @param n
	 * @return
	 */
	@Slot
	public BigInteger factorielle(int nombre) {
		BigInteger n = BigInteger.ONE;
		for (int i = 1; i <= nombre; i++) {
			n = n.multiply(BigInteger.valueOf(i));
		}
		return n;
	}

	/**
	 * retourne le nombre d’arrangements de p éléments pris parmi n avec n et p entier positifs ou nuls et p ≤ n
	 * @param n
	 * @param p
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal arrangement(BigDecimal n, BigDecimal p) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne le nombre de combinaisons de p éléments pris parmi n avec n et p entier positifs ou nuls et p ≤ n
	 * @param n
	 * @param p
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal combinaison(BigDecimal n, BigDecimal p) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne un vecteur de p tirages entiers pris entre m et n avec p entier positif, m et n entiers et m ≤ n
	 * @param p
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> tirageentier(BigDecimal p, BigDecimal m, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne un vecteur de p tirages réels pris entre a et b avec p entier positif, a et b réels et a ≤ b
	 * @param p
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> tiragereel(BigDecimal p, BigDecimal m, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la fréquence de n dans la suite de nombres s avec n entier
	 * @param n
	 * @param s
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal frequence(BigDecimal n, BigDecimal s) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la suite des fréquences de p tirages entiers pris entre m et n avec p entier positif, m et n entiers et m ≤ n.
	 * @param p
	 * @param m
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> frequencetirageentier(BigDecimal p, BigDecimal m, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * etourne la moyenne du vecteur de nombres v
	 * @param v
	 * @return moyennes de la liste 'nombres'
	 */
	@Slot
	public BigDecimal moyenne(List<BigDecimal> v) {
		BigDecimal total = BigDecimal.ZERO;
		for (BigDecimal integer : v) {
			total = total.add(integer);
		}
		return total.divide(new BigDecimal(v.size()), MathContext.DECIMAL32);
	}

	/**
	 * retourne la moyenne du vecteur de nombres v pondéré par le vecteur de nombres n avec v et n de même dimension et n un vecteur de nombres positifs ou nuls mais non tous nuls
	 * @param v
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal moyenneponderee(List<BigDecimal> v, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne l’écart type du vecteur de nombres v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal ecarttype(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne l’écart type du vecteur de nombres v pondéré par le vecteur de nombres n avec v et n de même dimension et n un vecteur de nombres positifs ou nuls mais non tous nuls
	 * @param v
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal ecarttypeponderee(List<BigDecimal> v, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la variance du vecteur de nombres v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal variance(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la variance du vecteur de nombres v pondéré par le vecteur de nombres n avec v et n de même dimension et n un vecteur de nombres positifs ou nuls mais non tous nuls
	 * @param v
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal varianceponderee(List<BigDecimal> v, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la médiane du vecteur de nombres v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal mediane(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la médiane du vecteur de nombres v pondéré par le vecteur de nombres n avec v et n de même dimension et n un vecteur de nombres positifs ou nuls mais non tous nuls
	 * @param v
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal medianeponderee(List<BigDecimal> v, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne les deux quartiles du vecteur de nombres v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> quartiles(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne les deux quartiles du vecteur de nombres v pondéré par le vecteur de nombres n avec v et n de même dimension et n un vecteur de nombres positifs ou nuls mais non tous nuls
	 * @param v
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> quartilesponderee(List<BigDecimal> v, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne les déciles D1 et D9 du vecteur de nombres v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> deciles(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne les déciles D1 et D9 du vecteur de nombres v pondéré par le vecteur de nombres n avec v et n de même dimension et n un vecteur de nombres positifs ou nuls mais non tous nuls
	 * @param v
	 * @param n
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> decilesponderee(List<BigDecimal> v, BigDecimal n) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la probabilité p(X ≤ t) lorsque X suit la loi exponentielle de paramètre λ avec λ positif
	 * @param lambda
	 * @param t
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal loiexp(BigDecimal lambda, BigDecimal t) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la probabilité p(X ≤ t) lorsque X suit la loi normale de paramètres et σ avec σ positif
	 * @param lambda
	 * @param xbar
	 * @param t
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal loinormale(BigDecimal lambda, BigDecimal xbar, BigDecimal t) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne les coefficients a et b de la droite de régression de y en x par la méthode des moindres carrés, d’équation y = ax + b, avec x et y des vecteurs de nombres de même dimension et x un vecteur de nombres non tous égaux
	 * @param x
	 * @param y
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> regressionyenx(BigDecimal x, BigDecimal y) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/*
	 * Outils
	 */

	/**
	 * retourne le vecteur v avec une seule occurrence de ses éléments dupliqués
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public List<BigDecimal> unique(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne la somme de tous les éléments du vecteur v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal somme(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}

	/**
	 * retourne le produit de tous les éléments du vecteur v
	 * @param v
	 * @return
	 * @throws GreffonException 
	 */
	@Slot
	public BigDecimal produit(List<BigDecimal> v) throws GreffonException {
		throw new GreffonException("Fonction non implémentée !");
	}
}
